/*
 * PulseAudioEnd.cpp
 *
 *  Created on: 2011-3-29
 *      Author: hao
 */

#include "SoundMachine.h"

#include "StreamEndPlugin.h"

#include <semaphore.h>

SoundMachine * pMachine = NULL;


std::function<bool( void *, size_t, size_t * )> write_function = NULL;

std::function<void()> drain_function = NULL;

bool StreamEndInit() {
	try {

		pMachine = SoundMachine::getSoundMachine();

		pMachine->Init();

	} catch (const Error & ex) {
		return false;
	}

	return true;
}

void StreamEndDestroy() {
    SoundMachine::DelectMachine();
}

bool CreateStream(int sample_format, int channels, int rate) {

	if (!write_function || !drain_function)
		return false;

	pa_sample_format_t trans_format;

	switch (sample_format) {
	case 8:

		trans_format = PA_SAMPLE_U8;

		break;
	case 16:

		trans_format = PA_SAMPLE_S16NE;

		break;

	case 24:

		trans_format = PA_SAMPLE_S24NE;

		break;

	case 32:

		trans_format = PA_SAMPLE_FLOAT32NE;

		break;

	default:

		return false;

	}

	try {
		pMachine->CreateStream(write_function, drain_function, trans_format,
				channels, rate);
	} catch (const Error & ex) {
		return false;
	}

	return true;

}

bool DestroyStream() {
	try {
		pMachine->DestroyStream();
	} catch (const Error & ex) {
		return false;
	}

	return true;
}

void StreamStop() {
	pMachine->StopStream();
}

void StreamStart() {
	pMachine->StreamResume();
}

void StreamPause() {
	pMachine->StreamPause();
}

void SetWriteStreamCallback( const std::function<bool( void *, size_t, size_t * )> & write_callback ) {

	write_function = write_callback;

}

void SetDrainStreamCallback( const std::function<void()> & drain_callback ) {

	drain_function = drain_callback;

}

void SetVolumeDB(double db) {

	pMachine->setVolumeDB(db);

}

void SetVolumeLinear(double linear) {

	pMachine->setVolumeLinear(linear);

}

void ChannleSetVolumeDB(int channle, double db) {

	pMachine->setChannelVolumeDb(channle, db);

}

void ChannleSetVolumeLinear(int channle, double linear) {

	pMachine->setChannelVolumeLinear(channle, linear);

}

unsigned long long StreamGetCurTime(){
    return pMachine->getCurTime() / 1000;
}